/*


 */

package jas.rpc.http;

import jas.rpc.RemoteObject;
import jas.rpc.client.RpcClient;
import jas.rpc.client.StubFactory;
import jas.rpc.*;
import jas.http.client.HttpClient;
import jas.http.request.HttpRequest;
import jas.http.response.HttpResponse;
import java.io.IOException;

/**
 *
 *
 */
public class RpcHttpClientImpl implements RpcClient {
    
    private HttpClient client;
    private RpcHttpClientFormatter formatter;
    private StubFactory stubFactory;
    
    public RpcHttpClientImpl(HttpClient client, RpcHttpClientFormatter formatter, StubFactory stubFactory) {
        this.client = client;
        this.formatter = formatter;
        this.stubFactory = stubFactory;
    }
    
    public <T> T remoteCall(Class<T> className, String objectId, String methodName, Object[] params, Class[] parameterClasses) 
            throws RemoteException {
        
        HttpRequest request = formatter.writeRequest(objectId, methodName, params, parameterClasses);
        HttpResponse response = null;
        try {
            response = client.sendRequest(request);
        } catch (IOException ex) {
            throw new ConnectionLostException(ex);
        }
        
        RpcResponse r = formatter.parseResponse(response, this, stubFactory);
        
        if (r.isException()) {
            throw new RemoteException(r.getException());
        }
        
        Object result = r.getResponse();
        
        // Object was sent by value, just return it
        return (T) result;
    }
    
    public <T> T getRemote(Class<T> className, String id) {
        return (T) stubFactory.getStub(new RemoteObject(className, id), this);
    }
    
}
